<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 7.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.ico">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha256-wiz7ZSCn/btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.css" integrity="sha256-6cQIC71/iBIYXFK+0RHAvwmjwWzkWd+r7v/BX3/vZDc=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/green/pace-theme-minimal.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"sumumm.github.io","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.19.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"mac"},"fold":{"enable":true,"height":300},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":true,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="本文主要是STM32开发——FSMC接口的一些相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:type" content="article">
<meta property="og:title" content="LV16-24-FSMC-02-FSMC基础">
<meta property="og:url" content="https://sumumm.github.io/post/8240821d.html">
<meta property="og:site_name" content="苏木">
<meta property="og:description" content="本文主要是STM32开发——FSMC接口的一些相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503121218218.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514192501538.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514165853284.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514170837547.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503124949215.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514171230341.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503145932595.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514173201606.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503153017891.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503153039615.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515121834603.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514201220924.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503160527408.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503160912905.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503161418932.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514172825795.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230520131132638.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515223604789.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515223612792.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515223752604.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515223802706.png">
<meta property="article:published_time" content="2023-06-04T14:07:28.000Z">
<meta property="article:modified_time" content="2025-06-13T16:25:57.013Z">
<meta property="article:author" content="苏木">
<meta property="article:tag" content="LV16-STM32开发">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503121218218.png">


<link rel="canonical" href="https://sumumm.github.io/post/8240821d.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://sumumm.github.io/post/8240821d.html","path":"post/8240821d.html","title":"LV16-24-FSMC-02-FSMC基础"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LV16-24-FSMC-02-FSMC基础 | 苏木</title>
  








    <script src="/js/browser_tools_disable.js"></script>

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<!-- hexo injector head_end start --><link rel="stylesheet" href="https://unpkg.com/hexo-next-tags-plus@latest/lib/tag_plus.css" media="defer" onload="this.media='all'"><!-- hexo injector head_end end --></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">苏木</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">我的学习之路</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>苏木的家</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类页<span class="badge">42</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档页<span class="badge">673</span></a></li><li class="menu-item menu-item-flink"><a href="/flink/" rel="section"><i class="fa fa-link fa-fw"></i>友人帐</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于我</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%80%E3%80%81FSMC%E7%AE%80%E4%BB%8B"><span class="nav-text">一、FSMC简介</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8C%E3%80%81FSMC%E6%A1%86%E5%9B%BE%E5%88%86%E6%9E%90"><span class="nav-text">二、FSMC框图分析</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-FSMC%E6%A1%86%E5%9B%BE"><span class="nav-text">1. FSMC框图</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E6%8E%A5%E5%8F%A3%E4%BF%A1%E5%8F%B7"><span class="nav-text">2. 接口信号</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-NOR%E9%97%AA%E5%AD%98%EF%BC%8C%E9%9D%9E%E5%A4%8D%E7%94%A8%E6%8E%A5%E5%8F%A3"><span class="nav-text">2.1 NOR闪存，非复用接口</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-NOR%E9%97%AA%E5%AD%98%EF%BC%8C%E5%A4%8D%E7%94%A8%E6%8E%A5%E5%8F%A3"><span class="nav-text">2.2 NOR闪存，复用接口</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-3-PSRAM%EF%BC%8C%E9%9D%9E%E5%A4%8D%E7%94%A8%E6%8E%A5%E5%8F%A3"><span class="nav-text">2.3 PSRAM，非复用接口</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-4-%E4%B8%8ESRAM%E7%9A%84%E6%8E%A5%E7%BA%BF%EF%BC%9F"><span class="nav-text">2.4 与SRAM的接线？</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E6%97%B6%E9%92%9F%E6%8E%A7%E5%88%B6%E9%80%BB%E8%BE%91"><span class="nav-text">3. 时钟控制逻辑</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E5%AD%98%E5%82%A8%E5%99%A8%E6%8E%A7%E5%88%B6%E5%99%A8"><span class="nav-text">4. 存储器控制器</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%89%E3%80%81%E5%AD%98%E5%82%A8%E5%99%A8%E6%98%A0%E5%B0%84%EF%BC%9F"><span class="nav-text">三、存储器映射？</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%9B%9B%E3%80%81NOR-PSRAM%E6%8E%A7%E5%88%B6%E5%99%A8"><span class="nav-text">四、NOR&#x2F;PSRAM控制器</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-Bank1%E7%9A%84%E5%9B%9B%E4%B8%AA%E5%8C%BA"><span class="nav-text">1. Bank1的四个区</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E5%9C%B0%E5%9D%80%E6%98%A0%E5%83%8F"><span class="nav-text">2. 地址映像</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%BC%82%E6%AD%A5%E8%AE%BF%E9%97%AE"><span class="nav-text">3. 同步与异步访问</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-1-%E4%B8%8D%E5%90%8C%E7%9A%84%E6%A8%A1%E5%BC%8F"><span class="nav-text">3.1 不同的模式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-%E5%AF%84%E5%AD%98%E5%99%A8%E9%85%8D%E7%BD%AE%EF%BC%9F"><span class="nav-text">3.2 寄存器配置？</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E6%A8%A1%E5%BC%8F1%E6%97%B6%E5%BA%8F"><span class="nav-text">4. 模式1时序</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-%E8%AF%BB%E6%97%B6%E5%BA%8F"><span class="nav-text">4.1 读时序</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-%E5%86%99%E6%97%B6%E5%BA%8F"><span class="nav-text">4.2 写时序</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-%E6%A8%A1%E5%BC%8FA%E6%97%B6%E5%BA%8F"><span class="nav-text">5. 模式A时序</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#5-1-%E8%AF%BB%E6%97%B6%E5%BA%8F"><span class="nav-text">5.1 读时序</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-2-%E5%86%99%E6%97%B6%E5%BA%8F"><span class="nav-text">5.2 写时序</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-%E7%9B%B8%E5%85%B3%E5%AF%84%E5%AD%98%E5%99%A8"><span class="nav-text">6. 相关寄存器</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#6-1-%E9%85%8D%E7%BD%AE%E5%AF%84%E5%AD%98%E5%99%A8%E8%A1%A8"><span class="nav-text">6.1 配置寄存器表</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-2-%E9%97%AA%E5%AD%98%E7%89%87%E9%80%89%E6%8E%A7%E5%88%B6%E5%AF%84%E5%AD%98%E5%99%A8FSMC-BCRx"><span class="nav-text">6.2 闪存片选控制寄存器FSMC_BCRx    </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-3-%E9%97%AA%E5%AD%98%E7%89%87%E9%80%89%E6%97%B6%E5%BA%8F%E5%AF%84%E5%AD%98%E5%99%A8-FSMC-BTRx"><span class="nav-text">6.3 闪存片选时序寄存器(FSMC_BTRx)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-4-%E9%97%AA%E5%AD%98%E5%86%99%E6%97%B6%E5%BA%8F%E5%AF%84%E5%AD%98%E5%99%A8FSMC-BWTRx"><span class="nav-text">6.4 闪存写时序寄存器FSMC_BWTRx)</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-NOR-PSRAM%E8%AE%BF%E9%97%AE%E5%8F%82%E6%95%B0"><span class="nav-text">7. NOR&#x2F;PSRAM访问参数</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%94%E3%80%81HAL%E5%BA%93%E5%87%BD%E6%95%B0"><span class="nav-text">五、HAL库函数</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E5%BA%93%E4%B8%AD%E7%9A%84%E5%AF%84%E5%AD%98%E5%99%A8"><span class="nav-text">1. 库中的寄存器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E5%88%9D%E5%A7%8B%E5%8C%96%E7%BB%93%E6%9E%84%E4%BD%93"><span class="nav-text">2. 初始化结构体</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-%E7%BB%93%E6%9E%84%E4%BD%93%E5%AE%9A%E4%B9%89"><span class="nav-text">2.1 结构体定义</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-%E6%88%90%E5%91%98%E8%AF%B4%E6%98%8E"><span class="nav-text">2.2 成员说明</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E6%97%B6%E5%BA%8F%E6%8E%A7%E5%88%B6%E7%BB%93%E6%9E%84%E4%BD%93"><span class="nav-text">3. 时序控制结构体</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-1-%E7%BB%93%E6%9E%84%E4%BD%93%E5%AE%9A%E4%B9%89"><span class="nav-text">3.1 结构体定义</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-%E6%88%90%E5%91%98%E8%AF%B4%E6%98%8E"><span class="nav-text">3.2 成员说明</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-3-%E6%97%B6%E5%BA%8F%E5%8F%82%E6%95%B0%E7%9A%84%E7%A1%AE%E5%AE%9A"><span class="nav-text">3.3 时序参数的确定</span></a></li></ol></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="苏木"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">苏木</p>
  <div class="site-description" itemprop="description">莫道桑榆晚，为霞尚满天</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">673</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">42</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">43</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author animated">
      <span class="links-of-author-item">
        <a href="https://github.com/sumumm" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;sumumm" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://sumumm.github.io/post/8240821d.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="苏木">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苏木">
      <meta itemprop="description" content="莫道桑榆晚，为霞尚满天">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="LV16-24-FSMC-02-FSMC基础 | 苏木">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LV16-24-FSMC-02-FSMC基础
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-06-04 22:07:28" itemprop="dateCreated datePublished" datetime="2023-06-04T22:07:28+08:00">2023-06-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">嵌入式开发</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/" itemprop="url" rel="index"><span itemprop="name">01HQ课程体系</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">LV16-STM32开发</span></a>
        </span>
    </span>

  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>13k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>47 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p>本文主要是STM32开发——FSMC接口的一些相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。</p>
<span id="more"></span>

<!-- Photo: https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/ -->

<details class="folding-tag" blue><summary> 点击查看使用工具及版本 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center" width=150px>Windows</td>        <td align="left">windows11</td>    </tr>    <tr>        <td align="center">Ubuntu</td>        <td align="left">Ubuntu16.04的64位版本</td>      </tr>    <tr>        <td align="center">VMware® Workstation 16 Pro</td>        <td align="left">16.2.3 build-19376536</td>      </tr>    <tr>        <td align="center">SecureCRT</td>        <td align="left">Version 8.7.2 (x64 build 2214)   -   正式版-2020年5月14日</td>      </tr>    <tr>        <td align="center">开发板</td>        <td align="left">正点原子 i.MX6ULL Linux阿尔法开发板</td>      </tr>    <tr>        <td align="center">uboot</td>        <td align="left">NXP官方提供的uboot，NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)</td>      </tr>    <tr>        <td align="center">linux内核</td>        <td align="left">linux-4.15(NXP官方提供)</td>      </tr>    <tr>        <td align="center">STM32开发板</td>        <td align="left">正点原子战舰V3(STM32F103ZET6)</td>      </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看本文参考资料 </summary>
              <div class='content'>
              <ul><li>通用</li></ul><table><tr><td align="center">分类  </td><td align="center">网址</td><td align="center">说明</td></tr><tr><td align="center" rowspan="4">官方网站</td><td align="left"><a href="https://www.arm.com/" target="_blank">https://www.arm.com/</a></td><td align="left">ARM官方网站，在这里我们可以找到Cotex-Mx以及ARMVx的一些文档</td></tr><tr>                                            <td align="left"><a href="https://www.st.com/content/st_com/zh.html" target="_blank">https://www.st.com/content/st_com/zh.html</a></td><td align="left">ST官方网站，在这里我们可以找到STM32的相关文档</td></tr><tr>                                            <td align="left"><a href="https://www.stmcu.com.cn/" target="_blank">https://www.stmcu.com.cn/</a></td><td align="left">意法半导体ST中文官方网站，在这里我们可以找到STM32的相关中文参考文档</td></tr><tr>                                            <td align="left"><a href="http://elm-chan.org/fsw/ff/00index_e.html" target="_blank">http://elm-chan.org/fsw/ff/00index_e.html</a></td><td align="left">FatFs文件系统官网</td></tr><tr><td align="center" rowspan="3">教程书籍</td><td align="left"><a href="STM32开发相关资料/01ARM参考资料/ARM Cortex-M3权威指南(中文).pdf" target="_blank">《ARM Cortex-M3权威指南》</a></td><td alirn="left" rowspan="3">ARM公司专家Joseph Yiu（姚文祥）的力作，中文翻译是NXP的宋岩</td></tr><tr>                                            <td align="left"><a href="STM32开发相关资料/01ARM参考资料/ARM Cortex-M0权威指南(中文).pdf" target="_blank">《ARM Cortex-M0权威指南》</a></td></tr><tr>                                            <td align="left"><a href="" target="_blank">《ARM Cortex-M3与Cortex-M4权威指南》</a></td></tr><tr><td align="center" rowspan="4">开发论坛</td><td align="left"><a href="http://47.111.11.73/forum.php" target="_blank">http://47.111.11.73/forum.php</a></td><td align="left">开源电子网，正点原子的资料下载及问题讨论论坛</td></tr><tr>                                            <td align="left"><a href="https://www.firebbs.cn/forum.php" target="_blank">https://www.firebbs.cn/forum.php</a></td><td align="left">国内Kinetis开发板-野火/秉火（刘火良）主持的论坛，现也做STM32和i.MX RT</td></tr><tr>                                            <td align="left"><a href="https://www.amobbs.com/index.php" target="_blank">https://www.amobbs.com/index.php</a></td><td align="left">阿莫（莫进明）主持的论坛，号称国内最早最火的电子论坛，以交流Atmel AVR系列单片机起家，现已拓展到嵌入式全平台，其STM32系列帖子有70W+。</td></tr><tr>                                            <td align="left"><a href="http://download.100ask.net/index.html" target="_blank">http://download.100ask.net/index.html</a></td><td align="left">韦东山嵌入式资料中心，有些STM32和linux的相关资料也可以来这里找。</td></tr><tr><td align="center" rowspan="3">博客参考</td><td align="left"><a href="http://www.openedv.com/" target="_blank">http://www.openedv.com/</a></td><td align="left">开源网-原子哥个人博客</td></tr><tr>                                            <td align="left"><a href="http://blog.chinaaet.com/jihceng0622" target="_blank">http://blog.chinaaet.com/jihceng0622</a></td><td align="left">博主是原Freescale现NXP的现场应用工程师</td></tr><tr>                                            <td align="left"><a href="https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/cortex-m-resources" target="_blank">cortex-m-resources</a></td><td align="left">这其实并不算是一个博客，这是ARM公司专家Joseph Yiu收集整理的所有对开发者有用的官方Cortex-M资料链接（也包含极少数外部资源链接）</td></tr></table><ul><li>STM32</li></ul><table>    <tr><td align="center" rowspan="2">STM32</td><td align="left"><a href="https://doc.embedfire.com/mcu/stm32/f103/hal_general/zh/latest/index.html" target="_blank">STM32 HAL库开发实战指南——基于F103系列开发板</a></td><td align="left">野火STM32开发教程在线文档</td></tr><tr>                                            <td align="left"><a href="https://doc.embedfire.com/mcu/stm32/f103badao/std/zh/latest/index.html" target="_blank">STM32库开发实战指南——基于野火霸道开发板</a></td><td align="left">野火STM32开发教程在线文档</td></tr></table><ul><li>SD卡</li></ul><table>    <tr><td align="left"><a href="https://www.sdcard.org/" target="_blank">SD Association</a></td><td align="left">提供了SD存储卡和SDIO卡系统规范</td></tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件下载 </summary>
              <div class='content'>
              <table>    <tr><td align="left"><a href="https://www.st.com/resource/en/datasheet/stm32f103ze.pdf" target="_blank">STM32F103xx英文数据手册</a></td><td align="left">STM32F103xC/D/E系列的英文数据手册</td></tr>    <tr><td align="left"><a href="https://www.stmcu.com.cn/Designresource/detail/localization_document%20/709978" target="_blank">STM32F103xx中文数据手册</a></td><td align="left">STM32F103xC/D/E系列的中文数据手册</td></tr>    <tr><td align="left"><a href="https://www.st.com/resource/en/reference_manual/rm0008-stm32f101xx-stm32f102xx-stm32f103xx-stm32f105xx-and-stm32f107xx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf" target="_blank">STM32F10xxx英文参考手册（RM0008）</a></td><td align="left">STM32F10xxx系列的英文参考手册</td></tr>    <tr><td align="left"><a href="https://www.stmcu.com.cn/Designresource/detail/localization_document%20/710001" target="_blank">STM32F10xxx中文参考手册（RM0008）</a></td><td align="left">STM32F10xxx系列的中文参考手册</td></tr>    <tr><td align="left"><a href="https://developer.arm.com/documentation/100165/0201/?lang=en" target="_blank">Arm Cortex-M3 处理器技术参考手册-英文版</a></td><td align="left">Cortex-M3技术参考手册-英文版</td></tr>    <tr><td align="left"><a href="https://www.st.com/resource/en/programming_manual/pm0056-stm32f10xxx20xxx21xxxl1xxxx-cortexm3-programming-manual-stmicroelectronics.pdf" target="_blank">STM32F10xxx Cortex-M3编程手册-英文版(PM0056)</a></td><td align="left">STM32F10xxx/20xxx/21xxx/L1xxxx系列Cortex-M3编程手册-英文版</td></tr>    <tr><td align="left"><a href="https://www.sdcard.org/downloads/pls/" target="_blank">SD卡相关资料——最新版本</a></td><td align="left">有关SD卡的一些资料可以从这里下载</td></tr>    <tr><td align="left"><a href="https://www.sdcard.org/downloads/pls/archives/" target="_blank">SD卡相关资料——历史版本</a></td><td align="left">有关SD卡的一些历史版本资料可以从这里下载，比如后边看的SD卡2.0协议</td></tr>    <tr><td align="left"><a href="./" target="_blank">SD 2.0 协议标准完整版</a></td><td align="left">这是一篇关于SD卡2.0协议的中文文档，还是比较有参考价值的，可以一看</td></tr></table>
              </div>
            </details>

<p>这一部分我们可以参考 [STM32中文参考手册](<a target="_blank" rel="noopener" href="https://www.stmcu.com.cn/Designresource/detail/localization_document">https://www.stmcu.com.cn/Designresource/detail/localization_document</a> &#x2F;710001)的 19 灵活的静态存储器控制器(FSMC) 一节。</p>
<h1 id="一、FSMC简介"><a href="#一、FSMC简介" class="headerlink" title="一、FSMC简介"></a><font size=3>一、FSMC简介</font></h1><p>FSMC，即灵活的静态存储控制器，能够与同步或异步存储器和 16 位 PC 存储器卡连接，STM32F1 的 FSMC 接口支持包括 SRAM、 NAND FLASH、 NOR FLASH 和 PSRAM 等存储器，但是不能驱动如SDRAM这种动态的存储器。  而在STM32F429系列的控制器中，它具有FMC外设，支持控制SDRAM存储器。</p>
<p>STM32F103ZET6的内部有64KB的SRAM，可以满足大部分的应用场景，但在一些采集数据比较多的项目、应用算法或GUI（ Graphical User Interface，图形用户界面） 等应用场景，内部SRAM可能就不够了，此时就需要外部扩展SRAM。  </p>
<p>STM32F103系列中， 100脚及以上的MCU，都有一个FSMC（ Flexible Static Memory Controller，灵活的静态存储器控制器） ， 该外设是STM32设计的一种存储器控制技术，仅适用STM32系列的MCU。 它可以驱动SRAM、 NOR Flash、 NAND Flash等存储器，但不能驱动SDRAM等动态存储器。  </p>
<h1 id="二、FSMC框图分析"><a href="#二、FSMC框图分析" class="headerlink" title="二、FSMC框图分析"></a><font size=3>二、FSMC框图分析</font></h1><h2 id="1-FSMC框图"><a href="#1-FSMC框图" class="headerlink" title="1. FSMC框图"></a><font size=3>1. FSMC框图</font></h2><p>在[STM32中文参考手册](<a target="_blank" rel="noopener" href="https://www.stmcu.com.cn/Designresource/detail/localization_document">https://www.stmcu.com.cn/Designresource/detail/localization_document</a> &#x2F;710001)的 19.2 框图一节，我们可以看到FSMC结构框图如下：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503121218218.png" alt="image-20230503121218218" style="zoom:50%;" />

<p>从上图可以看出，STM32 的 FSMC 将外部设备分为 3 类： NOR&#x2F;PSRAM 设备、 NAND设备、 PC 卡设备。他们共用地址数据总线等信号，他们具有不同的 CS 以区分不同的设备，  </p>
<h2 id="2-接口信号"><a href="#2-接口信号" class="headerlink" title="2. 接口信号"></a><font size=3>2. 接口信号</font></h2><p>这一部分我们可以查看[STM32中文参考手册](<a target="_blank" rel="noopener" href="https://www.stmcu.com.cn/Designresource/detail/localization_document">https://www.stmcu.com.cn/Designresource/detail/localization_document</a> &#x2F;710001)的 19.5.1 外部存储器接口信号。下边我们一起来看一下与NOR闪存和PSRAM接口的典型信号。<strong>注意</strong>：具有前缀 “ N ” 的信号表示低有效信号。这里说一下下边的复用和非复用是什么意思：</p>
<ul>
<li><p>非复用模式：16位数据线及26位地址线分开始用。推荐在144脚及以上的STM32产品上使用该模式。</p>
</li>
<li><p>复用模式：低16位数据&#x2F;地址线复用。在该模式下，推荐使用地址锁存器以区分数据与地址。</p>
</li>
</ul>
<h3 id="2-1-NOR闪存，非复用接口"><a href="#2-1-NOR闪存，非复用接口" class="headerlink" title="2.1 NOR闪存，非复用接口"></a><font size=3>2.1 NOR闪存，非复用接口</font></h3><table>
<thead>
<tr>
<th>FSMC信号名称</th>
<th>信号方向</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td>CLK</td>
<td>输出</td>
<td>时钟信号（ 用于同步访问的外部存储器）</td>
</tr>
<tr>
<td>A[25:0]</td>
<td>输出</td>
<td>地址总线</td>
</tr>
<tr>
<td>D[15:0]</td>
<td>输入&#x2F;输出</td>
<td>数据总线</td>
</tr>
<tr>
<td>NEx</td>
<td>输出</td>
<td>Bank1区域内片选信号， x&#x3D;1~4，每个区域大小为64MB</td>
</tr>
<tr>
<td>NOE</td>
<td>输出</td>
<td>读使能信号</td>
</tr>
<tr>
<td>NWE</td>
<td>输出</td>
<td>写使能信号</td>
</tr>
<tr>
<td>NWAIT</td>
<td>输入</td>
<td>NOR闪存要求FSMC等待的信号</td>
</tr>
</tbody></table>
<p>NOR闪存存储器是按16位的字寻址，最大容量达64M字节(26条地址线)。</p>
<h3 id="2-2-NOR闪存，复用接口"><a href="#2-2-NOR闪存，复用接口" class="headerlink" title="2.2 NOR闪存，复用接口"></a><font size=3>2.2 NOR闪存，复用接口</font></h3><table>
<thead>
<tr>
<th>FSMC信号名称</th>
<th>信号方向</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td>CLK</td>
<td>输出</td>
<td>时钟信号（ 用于同步访问的外部存储器）</td>
</tr>
<tr>
<td>A[25:16]</td>
<td>输出</td>
<td>地址总线</td>
</tr>
<tr>
<td>AD[15:0]</td>
<td>输入&#x2F;输出</td>
<td>16位复用的，双向地址&#x2F;数据总线</td>
</tr>
<tr>
<td>NEx</td>
<td>输出</td>
<td>Bank1区域内片选信号， x&#x3D;1~4，每个区域大小为64MB</td>
</tr>
<tr>
<td>NOE</td>
<td>输出</td>
<td>读使能信号</td>
</tr>
<tr>
<td>NWE</td>
<td>输出</td>
<td>写使能信号</td>
</tr>
<tr>
<td>NL(&#x3D;NADV)</td>
<td>输入</td>
<td>锁存使能(某些NOR闪存器件命名该信号为地址有效，NADV，也可以叫地址有效信号)</td>
</tr>
<tr>
<td>NWAIT</td>
<td>输入</td>
<td>NOR闪存要求FSMC等待的信号</td>
</tr>
</tbody></table>
<p>NOR闪存存储器是按16位的字寻址，最大容量达64M字节(26条地址线)。</p>
<h3 id="2-3-PSRAM，非复用接口"><a href="#2-3-PSRAM，非复用接口" class="headerlink" title="2.3 PSRAM，非复用接口"></a><font size=3>2.3 PSRAM，非复用接口</font></h3><p>非复用信号的PSRAM接口信号如下：</p>
<table>
<thead>
<tr>
<th>FSMC信号名称</th>
<th>信号方向</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td>CLK</td>
<td>输出</td>
<td>时钟信号（ 用于同步访问的外部存储器）</td>
</tr>
<tr>
<td>A[25:0]</td>
<td>输出</td>
<td>地址总线</td>
</tr>
<tr>
<td>D[15:0]</td>
<td>输入&#x2F;输出</td>
<td>双向数据总线</td>
</tr>
<tr>
<td>NEx</td>
<td>输出</td>
<td>Bank1区域内片选信号， x&#x3D;1~4，每个区域大小为64MB (PSRAM称其为NCE(Cellular RAM既CRAM))</td>
</tr>
<tr>
<td>NOE</td>
<td>输出</td>
<td>读使能信号</td>
</tr>
<tr>
<td>NWE</td>
<td>输出</td>
<td>写使能信号</td>
</tr>
<tr>
<td>NL(&#x3D;NADV)</td>
<td>输出</td>
<td>地址有效信号(存储器信号名称为：NADV)</td>
</tr>
<tr>
<td>NWAIT</td>
<td>输入</td>
<td>PSRAM要求FSMC等待的信号</td>
</tr>
<tr>
<td>NBL[1]</td>
<td>输出</td>
<td>高字节使能(存储器信号名称为：NUB)</td>
</tr>
<tr>
<td>NBL[0]</td>
<td>输出</td>
<td>低字节使能(存储器信号名称为：NLB)</td>
</tr>
</tbody></table>
<p>PSRAM存储器是按16位的字寻址，最大容量达64M字节(26条地址线)。</p>
<h3 id="2-4-与SRAM的接线？"><a href="#2-4-与SRAM的接线？" class="headerlink" title="2.4 与SRAM的接线？"></a><font size=3>2.4 与SRAM的接线？</font></h3><p>我们上一节学习 <a target="_blank" rel="noopener" href="https://www.issi.com/WW/pdf/62WV51216ALL.pdf"> IS62WV51216BLL</a>这款SRAM的一些基础知识，我们学习FSMC就是来驱动这个SRAM芯片的，那么SRAM这么多引脚是如何与SRAM引脚对应的呢？我来看一下 FSMC 与 SRAM 引脚对照表 ：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514192501538.png" alt="image-20230514192501538" style="zoom:50%;" />

<p>也就是如下表所示:</p>
<table>
<thead>
<tr>
<th>FSMC引脚名称</th>
<th>对应的FSMC引脚名</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>FSMC_NBL[1:0]</td>
<td>LB#，UB#</td>
<td>数据掩码信号</td>
</tr>
<tr>
<td>FSMC_A[18:0]</td>
<td>A[18:0]</td>
<td>行地址线，这里FSMC有25根，但只使用了19根</td>
</tr>
<tr>
<td>FSMC_D[15:0]</td>
<td>I&#x2F;O[15:0]</td>
<td>数据线，一共16根</td>
</tr>
<tr>
<td>FSMC_NWE</td>
<td>WE#</td>
<td>写入使能信号线</td>
</tr>
<tr>
<td>FSMC_NOE</td>
<td>OE#</td>
<td>输出使能信号线（读使能）</td>
</tr>
<tr>
<td>FSMC_NE[1:4]</td>
<td>CE#</td>
<td>片选信号</td>
</tr>
</tbody></table>
<p>由于大部分地址线 FSMC_A 都是使用到了 GPIOF、 GPIOG 端口，而 STM32VET6 等 144脚以下型号的芯片不具有这些端口，因此对于 144 脚以下的 STM32 芯片，无法扩展外部 SRAM，STM32ZET6 或以上型号的芯片具有 GPIOF、 GPIOG 等端口，因此想要扩展外部 SRAM 的时候，需要注意 STM32 芯片的选型。</p>
<p>其中比较特殊的 FSMC_NE 是用于控制 SRAM 芯片的片选控制信号线， STM32 具有FSMC_NE1&#x2F;2&#x2F;3&#x2F;4 号引脚，不同的引脚对应 STM32 内部不同的地址区域。例如，当 STM32 访问 0x68000000-0x6BFFFFFF 地址空间时， FSMC_NE3 引脚会自动设置为低电平，由于它连接到 SRAM 的 CE# 引脚，所以 SRAM 的片选被使能，而访问 0x60000000-0x63FFFFFF 地址时，FSMC_NE1 会输出低电平。当使用不同的 FSMC_NE 引脚连接外部存储器时， STM32 访问 SRAM的地址不一样，从而达到控制多块 SRAM 芯片的目的。各引脚对应的地址会在后面 四、NOR&#x2F;PSRAM控制器 小节说明。  </p>
<h2 id="3-时钟控制逻辑"><a href="#3-时钟控制逻辑" class="headerlink" title="3. 时钟控制逻辑"></a><font size=3>3. 时钟控制逻辑</font></h2><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514165853284.png" alt="image-20230514165853284" style="zoom: 33%;" />



<p>FSMC外设挂载在AHB总线上，时钟信号来自于HCLK(默认72MHz)，控制器的同步时钟输出就是由它分频得到。例如，NOR控制器的FSMC_CLK引脚输出的时钟，它可用于与同步类型的SRAM芯片进行同步通讯，它的时钟频率可通过FSMC_BTR寄存器的CLKDIV位配置，可以配置为HCLK的1&#x2F;2或1&#x2F;3，也就是说，若它与同步类型的SRAM通讯时，同步时钟最高频率为36MHz。我们将要驱动的SRAM为异步类型的存储器，不使用同步时钟信号，所以时钟分频配置不起作用。</p>
<h2 id="4-存储器控制器"><a href="#4-存储器控制器" class="headerlink" title="4. 存储器控制器"></a><font size=3>4. 存储器控制器</font></h2><p>面不同类型的引脚是连接到FSMC内部对应的存储控制器中的。NOR&#x2F;PSRAM&#x2F;SRAM设备使用相同的控制器，NAND&#x2F;PC卡设备使用相同的控制器，不同的控制器有专用的寄存器用于配置其工作模式。</p>
<p>控制SRAM的有FSMC_BCR1&#x2F;2&#x2F;3&#x2F;4控制寄存器、FSMC_BTR1&#x2F;2&#x2F;3&#x2F;4片选时序寄存器以及FSMC_BWTR1&#x2F;2&#x2F;3&#x2F;4写时序寄存器。每种寄存器都有4个，分别对应于4个不同的存储区域，各种寄存器介绍如下（后边还会再说明）：</p>
<ul>
<li>FSMC_BCR控制寄存器可配置要控制的存储器类型、数据线宽度以及信号有效极性能参数。</li>
<li>FMC_BTR时序寄存器用于配置SRAM访问时的各种时间延迟，如数据保持时间、地址保持时间等。</li>
<li>FMC_BWTR写时序寄存器与FMC_BTR寄存器控制的参数类似，它专门用于控制写时序的时间参数。</li>
</ul>
<h1 id="三、存储器映射？"><a href="#三、存储器映射？" class="headerlink" title="三、存储器映射？"></a><font size=3>三、存储器映射？</font></h1><p>FSMC连接好外部的存储器并初始化后，就可以直<strong>接通过访问地址来读写数据</strong>。FSMC访问存储器的方式与I2C EEPROM、SPI FLASH的不一样，后两种方式都需要控制I2C或SPI总线给存储器发送地址，然后获取数据；在程序里，这个地址和数据都需要分开使用不同的变量存储，并且访问时还需要使用代码控制发送读写命令。而使用FSMC外接存储器时，其<strong>存储单元是映射到STM32的内部寻址空间的</strong>；在程序里，<strong>定义一个指向这些地址的指针，然后就可以通过指针直接修改该存储单元的内容，FSMC外设会自动完成数据访问过程，读写命令之类的操作不需要程序控制</strong>。</p>
<p>作为STM32的外设，FSMC被映射在哪里？我们来回顾一下STM32的存储器映像：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514170837547.png" alt="image-20230514170837547" style="zoom:50%;" />

<p>图中左侧的是Cortex-M3内核的存储空间分配，右侧是STM32 FSMC外设的地址映射（我们可以查看<a target="_blank" rel="noopener" href="https://www.st.com/resource/en/datasheet/stm32f103ze.pdf">STM32F103xx数据手册</a>的4 Memory mapping）。可以看到FSMC的NOR&#x2F;PSRAM&#x2F;SRAM&#x2F;NAND FLASH以及PC卡的地址都在External RAM地址空间内。正是因为存在这样的地址映射，使得访问FSMC控制的存储器时，就跟访问STM32的片上外设寄存器一样。FSMC把整个External RAM存储区域分成了4个Bank区域，并分配了地址范围及适用的存储器类型，如NOR及SRAM存储器只能使用Bank1的地址。 </p>
<p>由图可知， 0x6000 0000<del>0x9FFF FFFF共计1GB空间为FSMC的存储器映射范围。 FSMC把这1GB空间，分为了4个固定大小的存储区域（ Bank1</del>4），每个大小为256MB， <strong>每个Bank都由一组独立的配置寄存器控制</strong>，相互之间不受干扰， 如下图：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503124949215.png" alt="image-20230503124949215" style="zoom: 33%;" />

<p>（1）Bank1（ 0x6000 000~0x6FFF FFFF）： 用于NOR&#x2F;PSRAM设备， 该区域又被分为4块，每块64MB，可连接4个NOR Flash设备或PSRAM设备，每个区域通过片选引脚NE[4:1]进行选择；</p>
<p>（2）Bank2（ 0x7000 000~0x7FFF FFFF）： 用于NAND Flash设备，每个存储块连接一个NAND闪存。</p>
<p>（3）Bank3（ 0x8000 000~0x8FFF FFFF）： 用于NAND Flash设备，每个存储块连接一个NAND闪存。</p>
<p>（4）Bank4（ 0x9000 000~0x9FFF FFFF）： 用于PC卡设备；  </p>
<h1 id="四、NOR-PSRAM控制器"><a href="#四、NOR-PSRAM控制器" class="headerlink" title="四、NOR&#x2F;PSRAM控制器"></a><font size=3>四、NOR&#x2F;PSRAM控制器</font></h1><p>由于我们后边要学习的如何驱动SRAM，因此重点分析NOR&#x2F;PSRAM控制器，即Bank1。 </p>
<h2 id="1-Bank1的四个区"><a href="#1-Bank1的四个区" class="headerlink" title="1. Bank1的四个区"></a><font size=3>1. Bank1的四个区</font></h2><p>STM32 的 FSMC 存储块 1（Bank1）被分为 4 个区，每个区管理 64M 字节空间，每个区都有独立的寄存器对所连接的存储器进行配置。  CPU需要28根AHB地址总线，才能寻址完Bank1的256MB空间（ 2^28&#x3D;256MB），这里用HADDR[27:0]表示需要的地址总线。 HADDR[25:0]对应连接外部存储器的FSMC_A[25:0]， HADDR[26:27]对应片选信号引脚NE[4:1]，这两个位主要是用于选择四个存储块之一。</p>
<table>
<thead>
<tr>
<th>Bank1所选区域</th>
<th>地址范围</th>
<th>片选引脚信号</th>
<th>HADDR[27:26]</th>
<th>HADDR[25:0]</th>
</tr>
</thead>
<tbody><tr>
<td>存储块1 NOR&#x2F;PSRAM 1</td>
<td>0x6000 0000~0x63FF FFFF</td>
<td>FSMC_NE1</td>
<td>00</td>
<td>FSMC_A[25:0]</td>
</tr>
<tr>
<td>存储块2 NOR&#x2F;PSRAM 2</td>
<td>0x6400 0000~0x67FF FFFF</td>
<td>FSMC_NE2</td>
<td>01</td>
<td>FSMC_A[25:0]</td>
</tr>
<tr>
<td>存储块3 NOR&#x2F;PSRAM 3</td>
<td>0x6800 0000~0x6BFF FFFF</td>
<td>FSMC_NE3</td>
<td>10</td>
<td>FSMC_A[25:0]</td>
</tr>
<tr>
<td>存储块4 NOR&#x2F;PSRAM 4</td>
<td>0x6C00 0000~0x6FFF FFFF</td>
<td>FSMC_NE4</td>
<td>11</td>
<td>FSMC_A[25:0]</td>
</tr>
</tbody></table>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514171230341.png" alt="image-20230514171230341" style="zoom:50%;" />

<p>如上图，当STM32访问0x68000000-0x6BFFFFFF地址空间时，会访问到Bank1的第3小块区域，相应的FSMC_NE3信号线会输出控制信号。</p>
<h2 id="2-地址映像"><a href="#2-地址映像" class="headerlink" title="2. 地址映像"></a><font size=3>2. 地址映像</font></h2><p>这一部分可以看[STM32中文参考手册](<a target="_blank" rel="noopener" href="https://www.stmcu.com.cn/Designresource/detail/localization_document">https://www.stmcu.com.cn/Designresource/detail/localization_document</a> &#x2F;710001)的19.4.1 NOR和PSRAM地址映像一节。<strong>CPU访问一个地址，只能读取一字节（ 8位 ）数据</strong>， 因此当外部存储器数据宽度不同时， 实际向存储器发送的地址也将有所不同。HADDR[25:0]包含外部存储器地址。HADDR是字节地址，而存储器访问不都是按字节访问，因此接到存储器的地址线依存储器的数据宽度有所不同</p>
<table>
<thead>
<tr>
<th>存储器数据宽度</th>
<th>向存储器发送的地址</th>
<th>存储器最大容量</th>
</tr>
</thead>
<tbody><tr>
<td>8位</td>
<td>HADDR[25:0]</td>
<td>64 Mbyte x 8 &#x3D; 512 Mbit</td>
</tr>
<tr>
<td>16位</td>
<td>HADDR[25:1] &gt;&gt; 1</td>
<td>64 Mbyte&#x2F;2 x 16 &#x3D; 512 Mbit</td>
</tr>
</tbody></table>
<p>当Bank1接的是8位宽度存储器的时候：HADDR[25:0]&rarr;FSMC_A[25:0]，当Bank1接的是16位宽度存储器的时候：HADDR[25:1]&rarr; FSMC_A[24:0]，HADDR[0]未接。需要注意的是，不论外部接8位&#x2F;16位宽设备，**FSMC_A[0]永远接在外部设备地址A[0]**。</p>
<p>我们来看一下分别接8位和16位的时候，地址是怎么对应的：</p>
<p>（1）假设某8位数据宽度的外部存储器接在Bank1的第一区，则FSMC_NE1连接该外部存储器片选，此时HADDR[26:27]值为0x00； FSMC_A[25:0]连接该外部存储器地址引脚。此时一个地址对应一字节（ 8位）数据，通过HADDR[25:0]寻址该外部存储器，得到8位数据。</p>
<p>（2）假设某16位数据宽度的外部存储器接在Bank1的第二区，则FSMC_NE2连接该外部存储器片选，此时HADDR[26:27]值为0x01， FSMC_A[25:0]连接该外部存储器地址引脚。此时一个地址对应两字节（ 16位）数据，通过HADDR[25:1]&gt;&gt;1寻址该外部存储器，得到16位数据。  </p>
<p>为什么对于16位数据宽度的外部存储器，要使用HADDR[25:1]&gt;&gt;1寻址？假设CPU想访问存储器0x0b0000地址数据，得到16位数据，此时CPU一次只能获取此16位的低8位。接着想通过0x0b0001地址访问剩下的8位，这个时候却访问的是下一个16位数据。但如果将访问地址右移1位，即无论是0x0b0000还是0x0b0001，都是0b0000，再通过NBLx切换高低8位，即可完整的获取存储器0x0b0000处的16位数据：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503145932595.png" alt="image-20230503145932595" style="zoom:30%;" />

<p>上边分析的这个过程，其实都是FSMC自动完成的，我们在编写程序的时候其实直接读写我们想要读写的地址，在FSMC内部会自动帮我们完成对存储器指定地址的访问。</p>
<h2 id="3-同步与异步访问"><a href="#3-同步与异步访问" class="headerlink" title="3. 同步与异步访问"></a><font size=3>3. 同步与异步访问</font></h2><h3 id="3-1-不同的模式"><a href="#3-1-不同的模式" class="headerlink" title="3.1 不同的模式"></a><font size=3>3.1 不同的模式</font></h3><p>NOR&#x2F;PSRAM控制器支持同步访问和异步访问，这里的同步、异步概念，与前面“ 同步&#x2F;异步通信 ”的概念类似。</p>
<ul>
<li><p>同步访问需要一个时钟信号作为收发双方的参考信号， FSMC使用HCLK分频后的时钟，作为与外部存储器的时钟同步信号FSMC_CLK。</p>
</li>
<li><p>异步访问无需时钟信号，通过提前制定规则保证数据传输的准确， 因此FSMC需要设置多个时间参数，比如数据建立时间（ Data-Phase Duration， DATAST）、 地址保持时间（ Address-hold Phase Duration， ADDHLD）和地址建立时间（ Address Setup Phase Duration ， ADDSET） 。</p>
</li>
</ul>
<p>NOR&#x2F;PSRAM控制器支持的器件类型众多， 不同的器件读写操作时序会有差异，因此控制器通过切换不同的模式，以使用不同的时序来支持不同的器件，我们后边多还是使用异步访问，NOR&#x2F;PSRAM 控制器的异步访问模式和同步访问模式如下表：</p>
<table>
    <tr><td align="center" colspan="2">访问模式</td><td align="center">描述</td><td align="center">需设置参数</td></tr>
    <tr><td align="left" colspan="2">同步模式</td><td align="left">根据同步时钟 FSMC_CK 读取多个顺序单元的数据</td><td align="left">CLKDIV、 DATLAT</td></tr>
    <tr><td align="left" rowspan="2">非扩展模式(异步)</td><td align="left">模式1</td><td align="left">适合SRAM/PSRAM(CRAM)的时序</td><td align="left">DATAST、 ADDSET</td></tr>
    <tr><td align="left">模式2/B</td><td align="left">适合NOR Flash的时序</td><td align="left">DATAST、 ADDSET</td></tr>
    <tr><td align="left" rowspan="4">扩展模式(异步)</td><td align="left">模式A   </td><td align="left">适合SRAM/PSRAM (CRAM) ， NOE片选 翻转的时序</td><td align="left">DATAST、 ADDSET</td></tr>
    <tr><td align="left">模式2/B </td><td align="left">适合NOR Flash的时序</td><td align="left">DATAST、 ADDSET</td></tr>
    <tr><td align="left">模式C</td><td align="left">适合NOR Flash ， NOE片选翻转的时序</td><td align="left">DATAST、 ADDSET</td></tr>
    <tr><td align="left">模式D</td><td align="left">适合带扩展地址的异步访问</td><td align="left">DATAST、 ADDSET、 ADDHLD </td></tr>
</table>


<p>【说明】ADDSET——地址建立时间 (Address setup phase duration) ，DATAST——数据保持时间 (Data-phase duration)，ADDHLD——地址保持时间 (Address-hold phase duration) 。</p>
<p>在非扩展模式下（ FSMC_BCRx寄存器的EXTMOD位置0），如果连接的是SRAM&#x2F;PSRAM，则默认访问模式为模式1，如果连接的是NOR Flash，则默认访问模式为模式2。在扩展模式下（ FSMC_BCRx寄存器的EXTMOD位置1），支持四种扩展模式：模式A、模式B、模式C和模式D。 也可以混合使用模式A、 B、 C、 D的读写操作，比如可以使用模式A进行读，模式B进行写。  我们后边学习的是SRAM，因此后边将会介绍模式1和模式A的时序。 </p>
<h3 id="3-2-寄存器配置？"><a href="#3-2-寄存器配置？" class="headerlink" title="3.2 寄存器配置？"></a><font size=3>3.2 寄存器配置？</font></h3><p>这么多的模式，都是通过寄存器配置来实现的，在[STM32中文参考手册](<a target="_blank" rel="noopener" href="https://www.stmcu.com.cn/Designresource/detail/localization_document">https://www.stmcu.com.cn/Designresource/detail/localization_document</a> &#x2F;710001)19.5.3 时序规则一节介绍的各种模式的时序图的后边，会有配置寄存器相关位的表格，我们可以参考这些表格来配置寄存器，使用不同的模式，例如：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514173201606.png" alt="image-20230514173201606" style="zoom:50%;" />

<h2 id="4-模式1时序"><a href="#4-模式1时序" class="headerlink" title="4. 模式1时序"></a><font size=3>4. 模式1时序</font></h2><p>这一部分我们可以看[STM32中文参考手册](<a target="_blank" rel="noopener" href="https://www.stmcu.com.cn/Designresource/detail/localization_document">https://www.stmcu.com.cn/Designresource/detail/localization_document</a> &#x2F;710001)的19.5.4 NOR闪存和PSRAM控制器时序图一节。</p>
<h3 id="4-1-读时序"><a href="#4-1-读时序" class="headerlink" title="4.1 读时序"></a><font size=3>4.1 读时序</font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503153017891.png" alt="image-20230503153017891" style="zoom: 67%;" />

<p>FSMC读外部存储器时，首先Bank1区域内片选信号引脚NEx拉低，选中外部存储器所在Bank；同时读使能信号引脚NOE拉低， 写使能信号引脚NWE保持高电平；接着地址总线A[25:0]在高低字节选择信号NBL[1:0]的配合下寻址， 经历（ ADDSET+1）个HCLK周期完成寻址； 在随后的（ DATASET+1） 个HCLK周期里， 外部存储器控制数据总线D[15:0]发送数据；最后，再经历2个HCLK周期后， Bank区域内片选信号引脚NEx和读使能信号引脚NOE都恢复为高电平。</p>
<h3 id="4-2-写时序"><a href="#4-2-写时序" class="headerlink" title="4.2 写时序"></a><font size=3>4.2 写时序</font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503153039615.png" alt="image-20230503153039615" style="zoom:67%;" />

<p>FSMC写外部存储器时，首先Bank区域内片选信号引脚NEx拉低，选中外部存储器所在Bank；同时读使能信号引脚NOE拉高，写使能信号引脚NEW先暂时保持高电平；接着地址总线A[25:0]在高低字节选择信号NBL[1:0]的配合下寻址，经历（ ADDSET+1）个HCLK周期完成寻址； 然后写使能信号引脚NWE拉低， 在随后的（ DATASET+1）个HCLK周期里， FSMC控制数据总线D[15:0]发送数据， 使能信号引脚NEW提前1个HCLK周期拉高；最后， Bank区域内片选信号引脚NEx恢复为高电平， 读使能信号引脚NOE都恢复为低电平。  </p>
<p>在写操作的最后一个HCLK周期可以保证NWE上升沿后地址和数据的保持时间，因为存在这个 HCLK周期，DATAST的数值必须大于0(DATAST &gt; 0)。</p>
<h2 id="5-模式A时序"><a href="#5-模式A时序" class="headerlink" title="5. 模式A时序"></a><font size=3>5. 模式A时序</font></h2><p>这一部分我们可以看[STM32中文参考手册](<a target="_blank" rel="noopener" href="https://www.stmcu.com.cn/Designresource/detail/localization_document">https://www.stmcu.com.cn/Designresource/detail/localization_document</a> &#x2F;710001)的19.5.4 NOR闪存和PSRAM控制器时序图一节。这一部分我们结合上一节学习的SRAM的时序图来学习，看完之后我们也就可以理解FSMC如何驱动SRAM了。</p>
<h3 id="5-1-读时序"><a href="#5-1-读时序" class="headerlink" title="5.1 读时序"></a><font size=3>5.1 读时序</font></h3><p>当内核发出访问某个指向外部存储器地址时， FSMC 外设会根据配置控制信号线产生时序访问存储器，下图中的是访问外部 SRAM 时 FSMC 外设的读写时序。  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515121834603.png" alt="image-20230515121834603" style="zoom:80%;" />

<p>该图表示一个存储器操作周期由地址建立周期 (ADDSET)、数据建立周期(DATAST) 以及 2 个 HCLK 周期组成。在地址建立周期中，地址线发出要访问的地址，数据掩码信号线指示出要读取地址的高、低字节部分，片选信号使能存储器芯片；地址建立周期结束后读使能信号线发出读使能信号，接着存储器通过数据信号线把目标数据传输给 FSMC， FSMC 把它交给内核。模式A读写访问外部存储器的时序和模式1基本类似， 如图所示。 主要区别在于FSMC读外部存储器时， 读使能信号引脚NOE不是一开始就拉高， 而是等寻址完后才拉低。      </p>
<p>我们具体看一下它与SRAM的时序图的对应关系：</p>
<p>（1）FSMC的存储器操作周期就相当于SRAM的tRC（读取周期时间），这段时间FSMC与SRAM的关系就是tRC对应(ADDSET+1)+(DATAST+1)+2这样一个时间段；</p>
<p>（2）我们看一下FSMC读时序标号①的地方，这里是从地址建立，到NOE拉低的时间，对应到SRAM的读时序中，就是图中字母A的位置，在SRAM中这个时间并没有明确的说明，不过可以参考比A处时间稍长一些的时间来确定这个标号①处的时间。</p>
<p>（2）SRAM的tAA（地址访问）时间，对应到FSMC的读时序中就如上图标注，它在FSMC中应该是(ADDSET+1)+(DATAST+1)这段时间。</p>
<p>（3）我们查看SRAM的手册知道当输出使能引脚OE#拉低后tODE时间后开始，SRAM将会输出数据，时间我们查询SRAm手册后发现是25ns，数据会保持所以我们在OE#拉低25ns之后采样即可，对应到FSMC的时序图中，我门们可以看到NOE信号拉低 （DATAST+1）个HCLK 时间后进行数据采样，也就是标号为②的这段时间，我们保证FSMC的这段时间大于25ns，这样就可以读取到SRAM的数据了。</p>
<p>（4）对于其他地方的一些小的区别，其实问题也不大，那些时间都非常短，对于这个HCLK，一般我们AHB总线时钟都是72M，所以一个HCLK时间就是1&#x2F;72M啦，计算出来的话大概就是13.8ns。</p>
<p>关于ADDSET和DATAST详细的确定过程可以看后边的读写外部SRAM实例，我在那篇笔记对照SRAM和FSMC时序详细分析了一下这两个参数如何确定。</p>
<h3 id="5-2-写时序"><a href="#5-2-写时序" class="headerlink" title="5.2 写时序"></a><font size=3>5.2 写时序</font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514201220924.png" alt="image-20230514201220924" style="zoom: 50%;" />

<p>写时序类似，区别是它的一个存储器操作周期仅由地址建立周期 (ADDSET) 和数据建立周期(DATAST) 组成，且在数据建立周期期间写使能信号线发出写信号，接着 FSMC 把数据通过数据线传输到存储器中。 模式A与模式1的区别是NOE的变化和相互独立的读写时序。从模式 A 的读写时序图，我们可以看出，读操作还存在额外的 2 个 HCLK 周期，用于数据存储，所以同样的配置读操作一般比写操作会慢一点。  </p>
<p>FSMC的写时序与SRAM的写时序也是对应的，这就就不再详细画图了，跟读时序一样的对应方式。我们注意观察这里，写时序使用的也是片选时序寄存器的ADDSET和DATAST位，这是同一个寄存器的同一个位，我们在进行读写的时候不会有问题嘛？一般来讲读写时序都差不多，所以可以用成同一个，但是若是读写时序要求的时长不同的话，我们还有一个寄存器可用，那就是写时序寄存器FSMC_BWTRx)。只需要在片选控制寄存器 1…4 (FSMC_BCR1…4)中开EXTMOD 位，也就是扩展模式使能 (Extended mode enable)，这样读写时序就可以使用不同的寄存器了。</p>
<h2 id="6-相关寄存器"><a href="#6-相关寄存器" class="headerlink" title="6. 相关寄存器"></a><font size=3>6. 相关寄存器</font></h2><h3 id="6-1-配置寄存器表"><a href="#6-1-配置寄存器表" class="headerlink" title="6.1 配置寄存器表"></a><font size=3>6.1 配置寄存器表</font></h3><p>相关的寄存器我们可以看 [STM32中文参考手册](<a target="_blank" rel="noopener" href="https://www.stmcu.com.cn/Designresource/detail/localization_document">https://www.stmcu.com.cn/Designresource/detail/localization_document</a> &#x2F;710001) 的19.7 FSMC寄存器地址映象（原英文手册没有这一节，中文手册翻译者整理添加的这一节）。STM32 的 FSMC 各 Bank 配置寄存器如下表：</p>
<table>
    <tr><td align="center">内部控制器</td><td align="center">存储块</td><td align="center">管理的地址范围</td><td align="center">支持的设备类型</td><td align="center">配置寄存器</td></tr>
    <tr><td align="center">NOR FLASH 控制器</td><td align="center">Bank1</td><td align="center">0X60000000~0X6FFFFFFF</td><td align="center">SRAM/ROM、NOR FLASH、PSRAM</td><td align="left">FSMC_BCR1/2/3/4<br>FSMC_BTR1/2/2/3<br>FSMC_BWTR1/2/3/4</td></tr>
    <tr><td align="center" rowspan="3">NAND FLASH/PC CARD控制器</td><td align="center">Bank2</td><td align="center">0X70000000~0X7FFFFFFF</td><td align="center" rowspan="2">NAND FLASH</td><td align="left"  rowspan="3">FSMC_PCR2/3/4<br>FSMC_SR2/3/4<br>FSMC_PMEM2/3/4<br>FSMC_PATT2/3/4<br>FSMC_PIO4</td></tr>
    <tr><td align="center">Bank3</td><td align="center">0X80000000~0X8FFFFFFF</td></tr>
    <tr><td align="center">Bank4</td><td align="center">0X90000000~0X9FFFFFFF</td><td align="center">PC Card</td></tr>
</table>


<p>对于 NOR FLASH 控制器，主要是通过 FSMC_BCRx、 FSMC_BTRx 和 FSMC_BWTRx 寄存器设置（其中 x&#x3D;1~4，对应 4 个区）。 通过这 3 个寄存器， 可以设置 FSMC 访问外部存储器的时序参数，拓宽了可选用的外部存储器的速度范围。 FSMC 的 NOR FLASH 控制器支持同步和异步突发两种访问方式。选用同步突发访问方式时， FSMC 将 HCLK(系统时钟)分频后，发送给外部存储器作为同步时钟信号 FSMC_CLK。  此时需要的设置的时间参数有 2 个：</p>
<p>（1）HCLK 与 FSMC_CLK 的分频系数(CLKDIV)，可以为 2～16 分频；</p>
<p>（2）同步突发访问中获得第 1 个数据所需要的等待延迟(DATLAT)。  </p>
<p>对于异步突发访问方式， FSMC 主要设置 3 个时间参数：地址建立时间(ADDSET)、数据建立时间(DATAST)和地址保持时间(ADDHLD)。 FSMC 综合了 SRAM／ ROM、 PSRAM 和 NORFlash 产品的信号特点，定义了 4 种不同的异步时序模型。 选用不同的时序模型时，需要设置不同的时序参数 ，这个在上一小节的笔记已经说过了可以看3. 同步与异步访问 这一小节的笔记。</p>
<p>在实际扩展时，根据选用存储器的特征确定时序模型，从而确定各时间参数与存储器读／写周期参数指标之间的计算关系；利用该计算关系和存储芯片数据手册中给定的参数指标，可计算出 FSMC 所需要的各时间参数，从而对时间参数寄存器进行合理的配置。  </p>
<h3 id="6-2-闪存片选控制寄存器FSMC-BCRx"><a href="#6-2-闪存片选控制寄存器FSMC-BCRx" class="headerlink" title="6.2 闪存片选控制寄存器FSMC_BCRx    "></a><font size=3>6.2 闪存片选控制寄存器FSMC_BCRx    </font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503160527408.png" alt="image-20230503160527408" style="zoom:50%;" />

<p>该寄存器我们在SRAM中用到的设置有： EXTMOD、 WREN、 MWID、 MTYP 和 MBKEN 这几个设置。</p>
<p>（1）EXTMOD：bit[14]，扩展模式使能位，也就是是否允许读写不同的时序，很明显，我们本章需要读写不同的时序，故该位需要设置为 1。为什么有这样一个位？为什么有扩展模式？前边在介绍模式A的读写时序的时候我们详细分析过，读写时序使用的都是片选时序寄存器的ADDSET和DATAST位，这是同一个寄存器的同一个位。一般来讲读写时序都差不多，可以用成同一个，但是若是读写时序要求的时长不同的话，我们还有一个寄存器可用，那就是写时序寄存器FSMC_BWTRx)。所以这个位就为使用不同的读写时序提供了配置方法。</p>
<p>（2）WREN：bit[12]，写使能位。我们需要向 SRAM 写数据，故该位必须设置为 1。</p>
<p>（3）MWID[1:0]：bit[5:4]，存储器数据总线宽度。 00，表示 8 位数据模式； 01 表示 16 位数据模式； 10 和 11 保留。</p>
<p>（4）MTYP[1:0]：bit[3:2]，存储器类型。 00 表示 SRAM、 ROM； 01 表示 PSRAM； 10 表示 NOR FLASH；11保留。</p>
<p>（5）MBKEN：bit[0]，存储块使能位。我们需要用到该存储块控制 SRAM，当然要使能这个存储块了。  </p>
<h3 id="6-3-闪存片选时序寄存器-FSMC-BTRx"><a href="#6-3-闪存片选时序寄存器-FSMC-BTRx" class="headerlink" title="6.3 闪存片选时序寄存器(FSMC_BTRx)"></a><font size=3>6.3 闪存片选时序寄存器(FSMC_BTRx)</font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503160912905.png" alt="image-20230503160912905" style="zoom:50%;" />

<p>这个寄存器包含了每个存储器块的控制信息，可以用于 SRAM、 ROM 和 NOR 闪存存储器。如果 FSMC_BCRx 寄存器中设置了 EXTMOD 位，则有两个时序寄存器分别对应读(本寄存器)和写操作(FSMC_BWTRx 寄存器)。因为我们要求读写分开时序控制，所以 EXTMOD 是使能了的，也就是本寄存器是读操作时序寄存器，控制读操作的相关时序。 我们驱动SRAM要用到的设置有：ACCMOD、 DATAST 和 ADDSET 这三个设置。</p>
<p>（1）ACCMOD[1:0]：访问模式。 00 表示访问模式 A； 01 表示访问模式 B； 10 表示访问模式 C；11 表示访问模式 D，我们用到模式 A，故设置为 00。</p>
<p>（2）DATAST[7:0]：数据保持时间。 0 为保留设置，其他设置则代表保持时间为: DATAST + 1 个 HCLK 时钟周期，最大为 255 个 HCLK 周期。对IS62WV51216 来说，其实就是OE#或者WE#低电平持续时间，最大为55ns。对STM32F1，一个HCLK&#x3D;13.8ns (1&#x2F;72M)，设置为3；对STM32F4，一个HCLK&#x3D;6ns(1&#x2F;168M) ，设置为8。</p>
<p>（3）ADDSET[3:0]：地址建立时间。其建立时间为： ADDSET + 1 个 HCLK 周期，最大为 15 个 HCLK周期。对IS62WV51216来说，访问周期最快位55ns，而我们前面的设置，已经可以保证访问周期不小于55ns，因此这个地址建立时间，我们可以直接设置为0即可。</p>
<p>【注意】如果未设置 FSMC_BCRx 寄存器的EXTMOD位，则读写共用这个时序寄存器。</p>
<h3 id="6-4-闪存写时序寄存器FSMC-BWTRx"><a href="#6-4-闪存写时序寄存器FSMC-BWTRx" class="headerlink" title="6.4 闪存写时序寄存器FSMC_BWTRx)"></a><font size=3>6.4 闪存写时序寄存器FSMC_BWTRx)</font></h3><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230503161418932.png" alt="image-20230503161418932" style="zoom:50%;" />

<p>该寄存器在本章用作写操作时序控制寄存器，需要用到的设置同样是： ACCMOD、 DATAST和 ADDSET 这三个设置。这三个设置的方法同 FSMC_BTRx 一模一样，只是这里对应的是写操作的时序， </p>
<p>（1）ACCMOD[1:0]：访问模式。00 模式A；01 模式B；10 模式C；11 模式D。</p>
<p>（2）DATAST[7:0]：数据保持时间，等于: DATAST(+1)个HCLK时钟周期，DATAST最大为255。考虑兼容性，对STM32F1，一个HCLK&#x3D;13.8ns (1&#x2F;72M)，设置为3；对STM32F4，一个HCLK&#x3D;6ns(1&#x2F;168M) ，设置为9。</p>
<p>（3）ADDSET[3:0]：地址建立时间。表示：ADDSET+1个HCLK周期，ADDSET最大为15。</p>
<h2 id="7-NOR-PSRAM访问参数"><a href="#7-NOR-PSRAM访问参数" class="headerlink" title="7. NOR&#x2F;PSRAM访问参数"></a><font size=3>7. NOR&#x2F;PSRAM访问参数</font></h2><p>对于不同类型的存储器，地址建立时间、地址保持时间等参数可能不一样，这些是我们需要配置的，下图是STM32提供的一些时间的可配置范围。具体配置成多少我们还是要看对应的存储器的芯片手册的时序。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230514172825795.png" alt="image-20230514172825795" style="zoom:50%;" />

<h1 id="五、HAL库函数"><a href="#五、HAL库函数" class="headerlink" title="五、HAL库函数"></a><font size=3>五、HAL库函数</font></h1><h2 id="1-库中的寄存器"><a href="#1-库中的寄存器" class="headerlink" title="1. 库中的寄存器"></a><font size=3>1. 库中的寄存器</font></h2><p>在 MDK 的寄存器定义里面，并没有定义 FSMC_BCRx、 FSMC_BTRx、 FSMC_BWTRx 等这个单独的寄存器，而是将他们进行了一些组合。FSMC_BCRx 和 FSMC_BTRx，组合成 BTCR[8]寄存器组，他们的对应关系如下：  </p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">BTCR[<span class="number">0</span>]---&gt;FSMC_BCR1， BTCR[<span class="number">1</span>]---&gt;FSMC_BTR1</span><br><span class="line">BTCR[<span class="number">2</span>]---&gt;FSMC_BCR2， BTCR[<span class="number">3</span>]---&gt;FSMC_BTR2</span><br><span class="line">BTCR[<span class="number">4</span>]---&gt;FSMC_BCR3， BTCR[<span class="number">5</span>]---&gt;FSMC_BTR3</span><br><span class="line">BTCR[<span class="number">6</span>]---&gt;FSMC_BCR4， BTCR[<span class="number">7</span>]---&gt;FSMC_BTR4</span><br></pre></td></tr></table></figure>

<p>FSMC_BWTRx 则组合成 BWTR[7]，他们的对应关系如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">BWTR[<span class="number">0</span>]---&gt;FSMC_BWTR1， BWTR[<span class="number">2</span>]---&gt;FSMC_BWTR2</span><br><span class="line">BWTR[<span class="number">4</span>]---&gt;FSMC_BWTR3， BWTR[<span class="number">6</span>]---&gt;FSMC_BWTR4</span><br><span class="line">BWTR[<span class="number">1</span>]、 BWTR[<span class="number">3</span>]和 BWTR[<span class="number">5</span>]保留，没有用到</span><br></pre></td></tr></table></figure>

<p>其实我们使用的是库函数，这里不需要太深究。</p>
<h2 id="2-初始化结构体"><a href="#2-初始化结构体" class="headerlink" title="2. 初始化结构体"></a><font size=3>2. 初始化结构体</font></h2><h3 id="2-1-结构体定义"><a href="#2-1-结构体定义" class="headerlink" title="2.1 结构体定义"></a><font size=3>2.1 结构体定义</font></h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="type">uint32_t</span> NSBank;           <span class="comment">// BANKx(NORSRAM)的区域(1-4)</span></span><br><span class="line">    <span class="type">uint32_t</span> DataAddressMux;   <span class="comment">// 设置地址总线与数据总线是否复用，仅用于 NOR</span></span><br><span class="line">    <span class="type">uint32_t</span> MemoryType;       <span class="comment">// 存储器类型</span></span><br><span class="line">    <span class="type">uint32_t</span> MemoryDataWidth;  <span class="comment">// 数据宽度位数</span></span><br><span class="line">    <span class="type">uint32_t</span> BurstAccessMode;  <span class="comment">// 设置是否使用突发访问模式，仅用于同步类型的存储器</span></span><br><span class="line">    <span class="type">uint32_t</span> WaitSignalPolarity; <span class="comment">// 等待信号的极性,仅用于同步类型的存储器</span></span><br><span class="line">    <span class="type">uint32_t</span> WrapMode;           <span class="comment">// 设置是否支持把非对齐的突发操作，仅用于同步类型的存储器</span></span><br><span class="line">    <span class="type">uint32_t</span> WaitSignalActive; <span class="comment">// 存储器是在等待周期之前的一个时钟周期还是等待周期期间使能 NWAIT,仅用于同步类型的存储器</span></span><br><span class="line">    <span class="type">uint32_t</span> WriteOperation;   <span class="comment">// 存储器写使能</span></span><br><span class="line">    <span class="type">uint32_t</span> WaitSignal;       <span class="comment">// 等待使能位,适用于突发模式访问</span></span><br><span class="line">    <span class="type">uint32_t</span> ExtendedMode;     <span class="comment">// 是否启用扩展模式</span></span><br><span class="line">    <span class="type">uint32_t</span> AsynchronousWait; <span class="comment">// 是否使能异步传输模式下的等待信号</span></span><br><span class="line">    <span class="type">uint32_t</span> WriteBurst;       <span class="comment">// 禁止突发写,适用于突发模式访问</span></span><br><span class="line">    <span class="type">uint32_t</span> PageSize;</span><br><span class="line">&#125; FSMC_NORSRAM_InitTypeDef;  </span><br></pre></td></tr></table></figure>

<h3 id="2-2-成员说明"><a href="#2-2-成员说明" class="headerlink" title="2.2 成员说明"></a><font size=3>2.2 成员说明</font></h3><p>（1）NSBank ：用于选择 FSMC 映射的存储区域，它的可选参数以及相应的内核地址映射范围见表 ：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230520131132638.png" alt="image-20230520131132638" style="zoom:50%;" />

<p>（2）DataAddressMux ：用于设置地址总线与数据总线是否复用 (Enable &#x2F;Disable)，在控制 NOR FLASH 时，可以地址总线与数据总线可以分时复用，以减少使用STM32 信号线的数量。</p>
<p>（3）MemoryType ：用于设置要控制的存储器类型，它支持控制的存储器类型为 SRAM、 PSRAM以及 NOR FLASH 。</p>
<p>（4）MemoryDataWidth ：用于设置要控制的存储器的数据宽度，可选择设置成8或16位。</p>
<p>（5）BurstAccessMode ：用于设置是否使用突发访问模式 ，突发访问模式是指发送一个地址后连续访问多个数据，非突发模式下每访问一个数据都需要输入一个地址，仅在控制同步类型的存储器时才能使用突发模式。</p>
<p>（6）WaitSignalPolarity ：用于设置等待信号的有效极性，即要求等待时，使用高电平还是低电平。</p>
<p>（7）WrapMode ：用于设置是否支持把非对齐的 AHB 突发操作分割成 2 次线性操作，该配置仅在突发模式下有效。</p>
<p>（8）WaitSignalActive ：用于配置在突发传输模式时，决定存储器是在等待状态之前的一 个数据周期有效还是在等待状态期间有效。</p>
<p>（9）WriteOperation：用于设置是否写使能，禁止写使能的话 FSMC 只能从存储器中读取数据，不能写入。</p>
<p>（10）WaitSignal：用于设置当存储器处于突发传输模式时，是否允许通过 NWAIT 信号插入等待状态。</p>
<p>（11）ExtendedMode：用于设置是否使用扩展模式，在非扩展模式下，对存储器读写的时序都只使用 FSMC_BCR 寄存器中的配置；在扩展模式下，对存储器的读写时序可以分开配置，读时序使用 FSMC_BCR 寄存器，写时序使用 FSMC_BWTR 寄存器的配置。</p>
<p>（12）AsynchronousWait：用于设置是否使能在同步传输时使用的等待信号，在控制同步类型的 NOR 或 PSRAM时，存储器可以使用 FSMC_NWAIT 引脚通知 STM32 需要等待。</p>
<h2 id="3-时序控制结构体"><a href="#3-时序控制结构体" class="headerlink" title="3. 时序控制结构体"></a><font size=3>3. 时序控制结构体</font></h2><h3 id="3-1-结构体定义"><a href="#3-1-结构体定义" class="headerlink" title="3.1 结构体定义"></a><font size=3>3.1 结构体定义</font></h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="type">uint32_t</span> AddressSetupTime;      <span class="comment">// 地址建立时间 ADDSET 范围:0~15 (模式 A 需要设置)</span></span><br><span class="line">    <span class="type">uint32_t</span> AddressHoldTime;       <span class="comment">// 地址保持时间 ADDHLD 范围:1~15，模式 A 未用到</span></span><br><span class="line">    <span class="type">uint32_t</span> DataSetupTime;         <span class="comment">// 数据建立时间 DATAST 范围:1~255 (模式 A 需要设置)</span></span><br><span class="line">    <span class="type">uint32_t</span> BusTurnAroundDuration; <span class="comment">// 总线恢复时间 BUSTURN 范围:0~15，设置总线转换周期，仅用于复用模式的 NOR 操作</span></span><br><span class="line">    <span class="type">uint32_t</span> CLKDivision;           <span class="comment">// 时钟分频因子 CLKDIV 范围:2~16，仅用于同步类型的存储器</span></span><br><span class="line">    <span class="type">uint32_t</span> DataLatency;           <span class="comment">// 数据产生时间 ACCMOD 范围:2~17，仅用于 NOR</span></span><br><span class="line">    <span class="type">uint32_t</span> AccessMode;            <span class="comment">// FSMC的模式</span></span><br><span class="line">&#125; FSMC_NORSRAM_TimingTypeDef;</span><br></pre></td></tr></table></figure>

<h3 id="3-2-成员说明"><a href="#3-2-成员说明" class="headerlink" title="3.2 成员说明"></a><font size=3>3.2 成员说明</font></h3><p>（1）AddressSetupTime ：设置地址建立时间，即 FSMC 模式 A 的读时或者写时序 中的 ADDSET值，它可以被设置为 0-0xF 个 HCLK 周期数，按默认配置， HCLK 的时钟频率为 72MHz，即一个 HCLK 周期为 1&#x2F;72 微秒。  </p>
<p>（2）AddressHoldTime ：设置地址保持时间，它可以被设置为 0-0xF 个 HCLK 周期数。  </p>
<p>（3）DataSetupTime ：设置数据建立时间，即 FSMC 模式 A 的读时序或者写时序 中的 DATAST值，它可以被设置为 0-0xF 个 HCLK 周期数。  </p>
<p>（4）BusTurnAroundDuration ：设置总线转换周期，在 NOR FLASH 存储器中，地址线与数据线可以分时复用，总线转换周期就是指总线在这两种状态间切换需要的延时，防止冲突。控制其它存储器时这个参数无效，配置为 0 即可。 </p>
<p>（5） CLKDivision ：设置时钟分频，它以 HCLK 时钟作为输入，经过 CLKDivision 分频后输出到 FSMC_CLK 引脚作为通讯使用的同步时钟。控制其它异步通讯的存储器时这个参数无效，配置为 0 即可。</p>
<p>（6）DataLatency ：设置数据保持时间，它表示在读取第一个数据之前要等待的周期数，该周期指同步时钟的周期，本参数仅用于同步 NOR FLASH 类型的存储器，控制其它类型的存储器时，本参数无效。  </p>
<p>（7）AccessMode ：设置存储器访问模式，不同的模式下 FSMC 访问存储器地址时引脚输出的时序不一样，可选 FSMC_AccessMode_A&#x2F;B&#x2F;C&#x2F;D 模式。一般来说控制 SRAM 时使用 A 模式。  </p>
<h3 id="3-3-时序参数的确定"><a href="#3-3-时序参数的确定" class="headerlink" title="3.3 时序参数的确定"></a><font size=3>3.3 时序参数的确定</font></h3><p>在这个时序结构体配置中，由于我们要控制的是 SRAM，所以选择 FSMC 为模式 A，在该模式下配置 FSMC 的控制时序结构体中，实际上只有地址建立时间 FSMC_AddressSetupTime（即 ADDSET 的值）以及数据建立时间 ，FSMC_DataSetupTime（即 DATAST 的值）成员的配置值是有效的，其它 SRAM 没使用到的成员值全配置为 0 即可。而且，这些成员值使用的单位为： 1 个 HCLK 的时钟周期，而 HCLK 的时钟频率为 72MHz，对应每个时钟周期为 1&#x2F;72 us。  </p>
<ul>
<li>读时序参数要满足的条件</li>
</ul>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515223604789.png" alt="image-20230515223604789" style="zoom:50%;" />

<p>从上边的时序图中，我们得到如下关系：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515223612792.png" alt="image-20230515223612792" style="zoom:50%;" />

<p>根据 FSMC 配置表达式的配置要求把时间单位 1&#x2F;72 微秒 (即 1000&#x2F;72 纳秒) 代入，可求得 ADDSET&#x3D; 0， DATAST&#x3D;1 时即可符合要求。如：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">tRC=ADDSET+<span class="number">1</span>+DATAST+<span class="number">1</span>+<span class="number">2</span> =( <span class="number">0</span>+<span class="number">1</span>+<span class="number">1</span>+<span class="number">1</span>+<span class="number">2</span> )*<span class="number">1000</span>/<span class="number">72</span> = <span class="number">69</span> ns &gt; <span class="number">55</span> ns</span><br><span class="line">tDOE=DATAST+<span class="number">1</span> = (<span class="number">1</span>+<span class="number">1</span>)*<span class="number">1000</span>/<span class="number">72</span> = <span class="number">27.7</span> &gt; <span class="number">25</span> ns</span><br></pre></td></tr></table></figure>

<p>不过，经实验总结出该配置在连续读取多个数据的时候会出现问题，更正确的配置为 ADDSET&#x3D;0，DATAST&#x3D;2，而这样的配置与写时序是一致的  </p>
<ul>
<li>写时序参数要满足的条件</li>
</ul>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515223752604.png" alt="image-20230515223752604" style="zoom:50%;" />

<p>从上边的时序图中，我们得到如下关系：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-24-FSMC-02-FSMC%E5%9F%BA%E7%A1%80/img/image-20230515223802706.png" alt="image-20230515223802706" style="zoom:50%;" />

<p>根据 FSMC 配置表达式的配置要求把时间单位 1&#x2F;72 微秒 (即 1000&#x2F;72 纳秒) 代入，可求得 ADDSET&#x3D; 0， DATAST&#x3D;2 时即可符合要求。如：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">tWC = ADDSET+<span class="number">1</span>+DATAST+<span class="number">1</span> =( <span class="number">0</span>+<span class="number">1</span>+<span class="number">2</span>+<span class="number">1</span> )*<span class="number">1000</span>/<span class="number">72</span> = <span class="number">55.555</span> ns &gt; <span class="number">55</span> ns</span><br><span class="line">tPWB = DATAST+<span class="number">1</span> = (<span class="number">2</span>+<span class="number">1</span>) *<span class="number">1000</span>/<span class="number">72</span> = <span class="number">41.6666</span> &gt; <span class="number">40</span> ns</span><br></pre></td></tr></table></figure>

<p>把计算得的参数赋值到时序结构体中的 FSMC_AddressSetupTime（即 ADDSET 的值）及FSMC_DataSetupTime（即 DATAST 的值）中，然后再把时序结构体作为指针赋值到下面的 FSMC初始化结构体中，作为读写的时序参数，最后再调用 FSMC_NORSRAMInit 函数即可把参数写入到相应的寄存器中。  </p>
<p>后边在读写外部SRAM实例中还会详细去学习时间参数怎么确定。</p>

    </div>

    
    
    

    <footer class="post-footer">




    <div>
        
            <div style="text-align:center;color: #ccc;font-size:14px;">
            ----------本文结束
            <i class="fas fa-fan fa-spin" style="color: #FF1493; font-size: 1rem"></i>
            感谢您的阅读----------
            </div>
        
    </div>





  
  <div class="my_post_copyright"> 
    <p><span>文章标题:</span><a href="/post/8240821d.html">LV16-24-FSMC-02-FSMC基础</a></p>
    <p><span>文章作者:</span><a href="/" title="欢迎访问 《苏木》 的学习笔记">苏木</a></p>
    <p><span>发布时间:</span>2023年06月04日 - 22:07</p>
    <p><span>最后更新:</span>2025年06月14日 - 00:25</p>
    <p><span>原始链接:</span><a href="/post/8240821d.html" title="LV16-24-FSMC-02-FSMC基础">https://sumumm.github.io/post/8240821d.html</a></p>
    <p><span>许可协议:</span><i class="fab fa-creative-commons"></i> <a rel="license" href= "https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
  </div>
  


          <div class="post-tags">
              <a href="/tags/LV16-STM32%E5%BC%80%E5%8F%91/" rel="tag"><i class="fa fa-tag"></i> LV16-STM32开发</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/post/294350a1.html" rel="prev" title="LV16-24-FSMC-03-读写外部SRAM实例">
                  <i class="fa fa-angle-left"></i> LV16-24-FSMC-03-读写外部SRAM实例
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/post/956dba12.html" rel="next" title="LV16-24-FSMC-01-外部SRAM基础">
                  LV16-24-FSMC-01-外部SRAM基础 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 2017 – 
    <span itemprop="copyrightYear">2025</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">苏木</span>
  </div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
      <span>站点总字数：</span>
    <span title="站点总字数">3.7m</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
      <span>站点阅读时长 &asymp;</span>
    <span title="站点阅读时长">225:26</span>
  </span>
</div>




    <span id="sitetime"></span>
    <script defer language=javascript>
        function siteTime()
        {
            window.setTimeout("siteTime()", 1000);
            var seconds = 1000;
            var minutes = seconds * 60;
            var hours = minutes * 60;
            var days = hours * 24;
            var years = days * 365;
            var today = new Date();
            var todayYear = today.getFullYear();
            var todayMonth = today.getMonth()+1;
            var todayDate = today.getDate();
            var todayHour = today.getHours();
            var todayMinute = today.getMinutes();
            var todaySecond = today.getSeconds();
            /*==================================================
            Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
            year        - 作为date对象的年份，为4位年份值
            month       - 0-11之间的整数，做为date对象的月份
            day         - 1-31之间的整数，做为date对象的天数
            hours       - 0(午夜24点)-23之间的整数，做为date对象的小时数
            minutes     - 0-59之间的整数，做为date对象的分钟数
            seconds     - 0-59之间的整数，做为date对象的秒数
            microseconds - 0-999之间的整数，做为date对象的毫秒数
            ==================================================*/
            var t1 = Date.UTC(2017, 
                              5, 
                              19, 
                              0, 
                              0, 
                              0); //北京时间
            var t2 = Date.UTC(todayYear,todayMonth,todayDate,todayHour,todayMinute,todaySecond);
            var diff = t2-t1;
            var diffYears = Math.floor(diff/years);
            var diffDays = Math.floor((diff/days)-diffYears*365);
            var diffHours = Math.floor((diff-(diffYears*365+diffDays)*days)/hours);
            var diffMinutes = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours)/minutes);
            var diffSeconds = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours-diffMinutes*minutes)/seconds);
            document.getElementById("sitetime").innerHTML="已在这里 "+diffYears+" 年 "+diffDays+" 天 "+diffHours+" 小时 "+diffMinutes+" 分钟 "+diffSeconds+" 秒";
        }
        siteTime();
    </script>



    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.umd.js" integrity="sha256-ytMJGN3toR+a84u7g7NuHm91VIR06Q41kMWDr2pq7Zo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js" integrity="sha256-mOFREFhqmHeQbXpK2lp4nA3qooVgACfh88fpJftLBbc=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>




  <script src="/js/third-party/fancybox.js"></script>

  <script src="/js/third-party/pace.js"></script>


  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>


 
        <div id="click-show-text"
            data-mobile = false
            data-text = 富强,民主,文明,和谐,自由,平等,公正,法制,爱国,敬业,诚信,友善
            data-fontsize = 15px
            data-random= false>
        </div>
       

      
        <script async src=https://cdn.jsdelivr.net/npm/hexo-next-mouse-effect@latest/click/showText.js></script>
      

      
    




    <script async src="/js/fancybox_param.js"></script>





<!-- APlayer本体 -->



</body>
</html>
